package com.sd365.common.util;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.*;

/**
 * @Description: 阿里云OSS服务相关工具类.
 * Java API文档地址：https://help.aliyun.com/document_detail/32008.html?spm=a2c4g.11186623.6.703.238374b4PsMzWf
 */
@Slf4j
public class AliyunOSSUtil {
    //文件路径
    private static String FILE_URL;
    //仓库名称
    public static final String bucketName= "bosssoft-study-platform-dev";
    //public static final String bucketName= "liziyou";
    //地域节点
    public static final String endpoint= "oss-cn-shenzhen.aliyuncs.com";
    //AccessKey ID
    public static final String accessKeyId= "LTAI5tGWMJPZfyLFRr2x4iYr";
    //public static final String accessKeyId= "LTAI5tMxD7peGVe7iwYYVtpV";
    //Access Key Secret
    public static final String accessKeySecret= "9WrHTCaAjmySuKyhLVDcEvndta1rfe";
    //public static final String accessKeySecret= "TDACi6s73kUKvzgd1oigo9bQQnrXk7";
    //仓库中的某个文件夹(自动生产)
    public static final String fileHost= "upload";

    /**
     * 启用线程池防止堵塞
     */
    private static final ExecutorService executorService = new ThreadPoolExecutor(
            20,
            50,
            3,
            TimeUnit.SECONDS,
            new LinkedBlockingDeque<>(3),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.DiscardOldestPolicy());


    /**
     * 上传文件。
     *
     * @param file  需要上传的文件路径
     * @param block 是否阻塞
     * @return 如果上传的文件是图片的话，会返回图片的"URL"，如果非图片的话会返回"非图片，不可预览。文件路径为：+文件路径"
     */
    public static String upLoad(MultipartFile file, Boolean block) {
        final OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try {

            // long stamp = new Date().getTime();
            long stamp = System.currentTimeMillis();

            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, stamp + file.getOriginalFilename(), file.getInputStream());

            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.YEAR, 5);

            URL url = ossClient.generatePresignedUrl(bucketName, stamp + file.getOriginalFilename(), calendar.getTime());
            if (block != null && block) {
                ossClient.putObject(putObjectRequest);
                ossClient.shutdown();
            } else {
                executorService.submit(() -> {
                    ossClient.putObject(putObjectRequest);
                    ossClient.shutdown();
                });
            }
            return url.toString();
        } catch (IOException e) {
            e.printStackTrace();
            ossClient.shutdown();
        }
        return null;
    }


    /**
     * 通过文件名下载文件
     *
     * @param objectName    要下载的文件名
     * @param localFileName 本地要创建的文件名
     */
    public static void downloadFile(String objectName, String localFileName) {

        // 创建OSSClient实例。
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        // 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖，不存在则新建。
        ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File(localFileName));
        // 关闭OSSClient。
        ossClient.shutdown();
    }

    /**
     * 列举 test 文件下所有的文件
     */
    public static void listFile(String directory) {
        // 创建OSSClient实例。
        OSSClient ossClient =null;
        try {
            ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
            // 构造ListObjectsRequest请求。
            ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);

            // 设置prefix参数来获取fun目录下的所有文件。
            listObjectsRequest.setPrefix(directory+"/");
            // 列出文件。
            ObjectListing listing = ossClient.listObjects(listObjectsRequest);
            // 遍历所有文件。
            log.info("Objects:");
            for (OSSObjectSummary objectSummary : listing.getObjectSummaries()) {
                log.info((objectSummary.getKey()));
            }
            // 遍历所有commonPrefix。
            log.info("CommonPrefixes:");
            for (String commonPrefix : listing.getCommonPrefixes()) {
                log.info(commonPrefix);
            }
        }finally {
            // 关闭OSSClient。
            ossClient.shutdown();
        }


    }

}
